<?php
//
//	file: sys/tree.form.class.php
//	author: Pierre ROGE pour GAIA (gaia.fr)
//	begin: 19/02/2008
//	version: 0.0.2 - 18/08/2008
//	license: http://opensource.org/licenses/gpl-license.php GNU General Public License (GPL)
//

if ( !defined('SYS') )
{
	die('Not allowed');
}

class sys_tree_form extends sys_form
{
	var $action;
	var $id;
	var $tree_name;
	var $tree;

	function __construct($api_name)
	{
		parent::__construct($api_name);
		$this->action = false;
		$this->id = false;
		$this->tree_name = false;
		$this->tree = false;
	}

	function __destruct()
	{
		if ( isset($this->tree) )
		{
			sys::kill($this->tree);
			unset($this->tree);
		}
		unset($this->tree_name);
		unset($this->id);
		unset($this->action);
		parent::__destruct();
	}

	function set()
	{
		$sys = &$GLOBALS[SYS];
		$io = &$sys->io;

		if ( $io->button('cancel_form') )
		{
			$form_buttons = array(
				'cancel_form' => array('legend' => 'cmd_cancel', 'accesskey' => 'cmd_cancel_accesskey'),
			);
			$form_fields = false;
		}
		else
		{
			// get action
			$this->action = false;
			$possible_actions = array('create', 'edit', 'delete');
			foreach ( $possible_actions as $action )
			{
				if ( $io->button($action) )
				{
					$this->action = $action;
					break;
				}
			}
			$this->id = false;
			if ( $this->action != 'create' )
			{
				$this->id = key($io->read($this->action, array(0)));
			}
			if ( !$this->action )
			{
				$this->action = $io->read(SYS_U_ACTION, '');
				$this->id = $this->action != 'create' ? $io->read(SYS_U_ITEM, 0) : false;
			}

			// define buttons
			$form_buttons = array(
				'submit_form' => array('legend' => 'cmd_submit', 'accesskey' => 'cmd_submit_accesskey'),
				'cancel_form' => array('legend' => 'cmd_cancel', 'accesskey' => 'cmd_cancel_accesskey'),
			);
			if ( $this->action == 'delete' )
			{
				$form_buttons['submit_form'] = array_merge($form_buttons['submit_form'], array('legend' => 'cmd_delete', 'accesskey' => 'cmd_delete_accesskey'));
			}

			// get tree & check id
			$class = $sys->ini_get($this->tree_name, 'class');
			$this->tree = new $class($this->api_name);
			$this->tree->set();

			// get form fields
			if ( !$this->action || !($form_fields = $this->get_fields($this->action)) )
			{
				trigger_error('err_unknown_action', E_USER_ERROR);
			}

			// check action against allowance
			if ( $this->action == 'delete' )
			{
				$this->tree->read_ancestors($this->id);
				if ( !$this->tree->data || !isset($this->tree->data[$this->id]) )
				{
					trigger_error('err_' . $this->tree->legend . '_not_exists', E_USER_ERROR);
				}
			}
			else
			{
				$this->tree->read();
				if ( ($this->action != 'create') && !isset($this->tree->data[$this->id]) )
				{
					trigger_error('err_' . $this->tree->legend . '_not_exists', E_USER_ERROR);
				}
			}
			if ( !$this->tree->allowed($this->id, $this->action) )
			{
				trigger_error('err_' . $this->tree->legend . '_not_allowed', E_USER_ERROR);
			}
		}
		parent::set($form_fields, $form_buttons);
	}

	function set_field(&$def, $name)
	{
		if ( $name == '_parent' )
		{
			$this->set_field_parent($def);
		}
		else if ( $this->id && isset($def['db.field']) )
		{
			$def['value'] = $this->tree->data[$this->id][ $def['db.field'] ];
		}
		parent::set_field($def, $name);
	}

	function set_field_parent(&$def)
	{
		$sys = &$GLOBALS[SYS];
		$io = &$sys->io;

		// get parent id from the form if exists, else from previous value
		$main_id = $io->exists('parent', '_POST') ? $io->read('parent', 0, '_POST') : false;
		if ( ($main_id === false) || !isset($this->tree->data[$main_id]) )
		{
			$main_id = isset($this->tree->data[$this->id][$this->tree->field_pid]) ? $this->tree->data[$this->id][$this->tree->field_pid] : 0;
		}

		// get parent list
		$parents = $orders = array();
		$this->tree->get_field_parent_lists($this->id, $main_id, $parents, $orders);

		// get brother input if any
		$order_id = $io->exists('order', '_POST') ? $io->read('order', 0, '_POST') : false;
		if ( ($order_id === false) || !isset($orders[$order_id]) )
		{
			$keys = array_keys($orders);
			if ( $this->id && isset($orders[$this->id]) )
			{
				$tkeys = array_flip($keys);
				$idx = $tkeys[$this->id] - 1;
				unset($tkeys);
			}
			else
			{
				$idx = count($keys) - 1;
			}
			$order_id = $idx >= 0 ? $keys[$idx] : 0;
			unset($keys);
		}

		// remove the edited id from the list
		if ( $this->id && isset($orders[$this->id]) )
		{
			unset($orders[$this->id]);
		}
		$def['parent'] = array(
			'id' => $this->id,
			'legend.align' => 'right',
			'value' => $main_id,
			'options' => $parents,
		);
		$def['order'] = array(
			'legend.align' => 'right',
			'value' => $order_id,
			'options' => $orders,
		);
	}

	function validate_field_parent(&$fields)
	{
		$parent_id = $this->fields['_parent']->fields['parent']->value;
		$order_id = $this->fields['_parent']->fields['order']->value;
		$fields[$this->tree->field_lid] = $parent_id == $order_id ? $this->tree->data[$order_id][$this->tree->field_lid] + 1 : $this->tree->data[$order_id][$this->tree->field_rid] + 1;
		$fields[$this->tree->field_rid] = $fields[$this->tree->field_lid] + ($this->id ? $this->tree->data[$this->id][$this->tree->field_rid] - $this->tree->data[$this->id][$this->tree->field_lid] : 1);
		$fields[$this->tree->field_pid] = $parent_id;
	}

	function validate()
	{
		$sys = &$GLOBALS[SYS];
		$api = &$GLOBALS[$this->api_name];

		$error = &$sys->error;
		$db = &$api->db;

		parent::validate();
		if ( !$this->validated || $error->warnings )
		{
			$this->validated = false;
			return false;
		}

		// get fields from form
		if ( $this->action != 'delete' )
		{
			$fields = array();
			$keys = array_keys($this->fields);
			foreach ( $keys as $key )
			{
				if ( ($key == '_parent') && !$this->fields[$key]->output )
				{
					$this->validate_field_parent($fields);
				}
				else if ( $this->fields[$key]->db_field && !$this->fields[$key]->output )
				{
					$fields[ $this->fields[$key]->db_field ] = $this->fields[$key]->value;
				}
			}
		}

		// proceed
		if ( $this->action == 'create' )
		{
			$this->tree->insert($fields);
			$return_msg = $this->tree->legend . '_created';
		}
		else if ( $this->action == 'edit' )
		{
			$this->tree->update($this->id, $fields);
			$return_msg = $this->tree->legend . '_updated';
		}
		else if ( $this->action == 'delete' )
		{
			$this->tree->delete($this->id);
			$return_msg = $this->tree->legend . '_deleted';
		}
		$api->feedback($return_msg, array('backto_' . $this->tree->legend => $api->url('', array(SYS_U_MODE => $api->mode))));
	}

	function display()
	{
		$sys = &$GLOBALS[SYS];
		$tpl = &$sys->tpl;
		$api = &$GLOBALS[$this->api_name];

		$api->set_resource('jscripts', array(
			$sys->root . 'styles/sys.jscripts/sys.js',
			$sys->root . 'styles/sys.jscripts/sys_ajax.js',
			$sys->root . 'styles/sys.jscripts/sys_ajax_lists.js',
		));

		parent::display();
		$tpl->hide(array(SYS_U_ACTION => $this->action));
		if ( $this->id )
		{
			$tpl->hide(array(SYS_U_ITEM => $this->id));
		}

		$scripts_title = array(
			'create' => array('title' => $this->tree->legend . '_create_title', 'explain' => $this->tree->legend . '_create_title_explain'),
			'edit' => array('title' => $this->tree->legend . '_edit_title', 'explain' => $this->tree->legend . '_edit_title_explain'),
			'delete' => array('title' => $this->tree->legend . '_delete_title', 'explain' => $this->tree->legend . '_delete_title_explain'),
		);
		$tpl->add(array(
			'SCRIPT_TITLE' => $scripts_title[$this->action]['title'],
			'SCRIPT_TITLE_EXPLAIN' => $scripts_title[$this->action]['explain'],
		));
		return 'form_generic';
	}

	function get_fields($form)
	{
		$sys = &$GLOBALS[SYS];
		$sys->ini_get('form.fields', 'class');
		$sys->ini_get('tree.fields', 'class');
		return false;
	}
}

?>